import os
import json
from User_Management.config import DATA_STORAGE_DIR, DATA_FILE_EXTENSION, DATA_MAIN_FILE
from datetime import datetime

# 修正导入语句
from User_Management.user_classes import User, Student, Teacher, Administrator
from Course_Management_and_Enrollment.course_task_classes import Course
from Assignment_and_Grading.course_task_classes import Assignment



# ==============================
def ensure_storage_dir():
    """创建数据存储目录(若不存在),避免文件写入时路径错误"""
    if not os.path.exists(DATA_STORAGE_DIR):
        os.makedirs(DATA_STORAGE_DIR)
        print(f"已创建数据存储目录:{DATA_STORAGE_DIR}")



# ==============================
# 1. 用户数据持久化(适配Eason模块)
# ==============================
# 获取统一的数据文件路径
def get_data_file_path():
    """获取统一的数据文件路径"""
    return os.path.join(DATA_STORAGE_DIR, DATA_MAIN_FILE)

# 修改保存用户数据的函数
def save_users(users: list):
    """保存用户数据到统一的数据文件"""
    try:
        # 读取现有数据
        all_data = {}
        if os.path.exists(get_data_file_path()):
            with open(get_data_file_path(), 'r', encoding='utf-8') as f:
                all_data = json.load(f)
                
        # 更新用户数据部分
        user_data_list = []
        user_ids = set()  # 用于去重
        
        for user in users:
            if user.user_id in user_ids:
                continue  # 跳过重复用户
            user_ids.add(user.user_id)
            
            # 通用用户数据
            user_data = {
                "user_type": user.__class__.__name__,  # 标记用户类型
                "user_id": user.user_id,
                "username": user.username,
                "_password": user._password,  # 存储加密后的密码
                "email": user.email,
                "role": user.role
            }

            # 补充学生专属数据
            if isinstance(user, Student):
                user_data.update({
                    "student_id": user.student_id,
                    "enrolled_courses": [course.course_id for course in user.enrolled_courses],
                    "submitted_assignments": [
                        {
                            "assignment_id": sub["assignment_id"],
                            "course_id": sub["course_id"],
                            "content": sub["content"],
                            "submit_time": sub["submit_time"].isoformat(),
                            "is_late": sub["is_late"],
                            "score": sub["score"],
                            "status": sub.get("status", "submitted")
                        }
                        for sub in user.submitted_assignments
                    ],
                    "grades": {course.course_id: score for course, score in user.grades.items()}
                })

            # 补充教师专属数据
            elif isinstance(user, Teacher):
                user_data.update({
                    "teacher_id": user.teacher_id,
                    "managed_courses": [course.course_id for course in user.managed_courses],
                    "created_assignments": [assign.assignment_id for assign in user.created_assignments]
                })

            # 补充管理员专属数据
            elif isinstance(user, Administrator):
                user_data.update({
                    "admin_id": user.admin_id,
                    "system_users": [u.user_id for u in user.system_users],
                    "all_courses": [course.course_id for course in user.all_courses]
                })

            user_data_list.append(user_data)

        # 保存完整数据
        all_data['users'] = user_data_list
        with open(get_data_file_path(), 'w', encoding='utf-8') as f:
            json.dump(all_data, f, indent=4, ensure_ascii=False)
        print(f"用户数据已保存至:{get_data_file_path()}")
        return True
    except Exception as e:
        print(f"保存用户数据失败: {e}")
        return False

# 修改加载用户数据的函数
def load_users(courses: list = None, assignments: list = None) -> list:
    """从统一的数据文件加载用户数据"""
    try:
        # 构建课程ID-实例映射(便于快速关联)
        course_id_map = {course.course_id: course for course in (courses or [])}
        # 构建作业ID-实例映射(便于快速关联)
        assignment_id_map = {assign.assignment_id: assign for assign in (assignments or [])}
        
        # 读取数据文件
        file_path = get_data_file_path()
        if not os.path.exists(file_path):
            print(f"用户数据文件不存在:{file_path},返回空列表")
            return []

        # 读取JSON文件
        with open(file_path, "r", encoding="utf-8") as f:
            all_data = json.load(f)
            
        users = []
        if 'users' in all_data:
            user_ids = set()  # 用于去重
            for user_data in all_data['users']:
                if user_data["user_id"] in user_ids:
                    continue  # 跳过重复用户
                user_ids.add(user_data["user_id"])
                
                # 修复:检查是否有user_type字段,如果没有则使用role字段
                if "user_type" not in user_data:
                    # 根据role字段推断用户类型
                    role = user_data.get("role", "")
                    if role == "student":
                        user_type = "Student"
                    elif role == "teacher":
                        user_type = "Teacher"
                    elif role == "admin":
                        user_type = "Administrator"
                    else:
                        user_type = "User"
                else:
                    user_type = user_data["user_type"]

                common_attrs = {
                    "user_id": user_data["user_id"],
                    "username": user_data["username"],
                    "_password": user_data.get("_password", user_data.get("password", "")),  # 兼容password字段
                    "email": user_data["email"],
                    "role": user_data["role"]
                }

                # 恢复Student实例
                # 恢复Student实例
                if user_type == "Student":
                    student = Student(
                        user_id=common_attrs["user_id"],
                        username=common_attrs["username"],
                        password=common_attrs["_password"],
                        email=common_attrs["email"],
                        # 删除role参数,因为Student类构造函数不接受这个参数
                        is_encrypted=True
                    )
                    # 恢复学生专属属性
                    student.student_id = user_data["student_id"]
                    # 关联已选课程
                    student.enrolled_courses = [
                        course_id_map[course_id] for course_id in user_data["enrolled_courses"]
                        if course_id in course_id_map
                    ]
                    # 关联已提交作业
                    student.submitted_assignments = []
                    for sub in user_data.get("submitted_assignments", []):
                        submission_dict = {
                            "assignment_id": sub["assignment_id"],
                            "course_id": sub.get("course_id", None),
                            "content": sub["content"],
                            "submit_time": datetime.fromisoformat(sub["submit_time"]),
                            "is_late": sub.get("is_late", False),
                            "score": sub.get("score", None),
                            "status": sub.get("status", "submitted")
                        }
                        student.submitted_assignments.append(submission_dict)
                    # 关联成绩
                    student.grades = {
                        course_id_map[course_id]: score 
                        for course_id, score in user_data.get("grades", {}).items()
                        if course_id in course_id_map
                    }
                    users.append(student)

                # 恢复Teacher实例
                elif user_type == "Teacher":
                    teacher = Teacher(
                        user_id=common_attrs["user_id"],
                        username=common_attrs["username"],
                        password=common_attrs["_password"],
                        email=common_attrs["email"],
                        is_encrypted=True
                    )
                    # 恢复教师专属属性
                    teacher.teacher_id = user_data["teacher_id"]
                    teacher.managed_courses = [
                        course_id_map[course_id] for course_id in user_data["managed_courses"]
                        if course_id in course_id_map
                    ]
                    teacher.created_assignments = [
                        assignment_id_map[assign_id] for assign_id in user_data["created_assignments"]
                        if assign_id in assignment_id_map
                    ]
                    users.append(teacher)

                # 恢复Administrator实例
                elif user_type == "Administrator":
                    admin = Administrator(
                        user_id=common_attrs["user_id"],
                        username=common_attrs["username"],
                        password=common_attrs["_password"],
                        email=common_attrs["email"],
                        is_encrypted=True
                    )
                    # 恢复管理员专属属性
                    admin.admin_id = user_data.get("admin_id", f"ADMIN_{os.urandom(4).hex().upper()}")
                    # 关联系统用户
                    admin.system_users = user_data.get("system_users", [])
                    admin.all_courses = [
                        course_id_map[course_id] for course_id in user_data.get("all_courses", [])
                        if course_id in course_id_map
                    ]
                    users.append(admin)
        
        print(f"✅ 加载了 {len(users)} 个用户")
        return users
    except Exception as e:
        print(f"加载用户数据时出错: {e}")
        return []


# ==============================
# 2. 课程与选课数据持久化(适配Yori模块)
# ==============================
def save_courses_and_enrollment(courses: list[object], enrollment_system: object):
    # 延迟导入
    from Course_Management_and_Enrollment.system_modules import EnrollmentSystem
    # 延迟导入
    from Course_Management_and_Enrollment.course_task_classes import Course
    """
    保存课程数据与选课系统数据
    适配Yori定义的Course类属性(course_id、course_name等)与EnrollmentSystem类属性(enrollment_records)
    """
    ensure_storage_dir()
    # 课程数据存储路径
    course_file_path = os.path.join(DATA_STORAGE_DIR, f"courses{DATA_FILE_EXTENSION}")
    # 选课记录存储路径
    enrollment_file_path = os.path.join(DATA_STORAGE_DIR, f"enrollment{DATA_FILE_EXTENSION}")

    # 1. 保存课程数据(Yori定义的Course类属性)
    course_data_list = []
    for course in courses:
        course_data = {
            "course_id": course.course_id,
            "course_name": course.course_name,
            "course_description": course.course_description,
            "teacher_id": course.teacher.teacher_id if course.teacher else None,  # 关联教师ID
            "max_students": course.max_students,
            "enrolled_students": [student.student_id for student in course.enrolled_students],  # 存储学生ID
            "course_assignments": [assign.assignment_id for assign in course.course_assignments]  # 存储作业ID
        }
        course_data_list.append(course_data)

    with open(course_file_path, "w", encoding="utf-8") as f:
        json.dump(course_data_list, f, indent=4, ensure_ascii=False)
    print(f"课程数据已保存至:{course_file_path}")

    # 2. 保存选课系统数据(Yori定义的EnrollmentSystem类属性)
    enrollment_data = {
        "enrollment_records": [
            {"student_id": record[0].student_id, "course_id": record[1].course_id, "enroll_time": record[2].isoformat()}
            for record in enrollment_system.enrollment_records
        ]  # 存储学生ID、课程ID、选课时间
    }

    with open(enrollment_file_path, "w", encoding="utf-8") as f:
        json.dump(enrollment_data, f, indent=4, ensure_ascii=False)
    print(f"选课数据已保存至:{enrollment_file_path}")


def load_courses_and_enrollment(teachers: list[object], students: list[object], assignments: list[object]) -> tuple[list[object], object]:
    from Course_Management_and_Enrollment.system_modules import EnrollmentSystem
    from Course_Management_and_Enrollment.course_task_classes import Course
    from Assignment_and_Grading.course_task_classes import Assignment
    import datetime
    import logging
    
    # 配置日志记录
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
    logger = logging.getLogger('data_persistence')
    
    """
    加载课程数据与选课系统数据
    需传入已加载的Teacher/Student/Assignment实例,用于关联课程与教师/学生/作业
    """
    try:
        # 初始化默认返回值
        courses = []
        enrollment_system = EnrollmentSystem()
        
        # 读取统一数据文件
        file_path = get_data_file_path()
        if not os.path.exists(file_path):
            logger.warning(f"数据文件不存在:{file_path},返回空列表与空选课系统")
            return courses, enrollment_system
        
        # 读取数据
        with open(file_path, "r", encoding="utf-8") as f:
            all_data = json.load(f)
        
        # 从统一数据中提取课程数据
        course_data_list = all_data.get('courses', [])
        enrollment_data = all_data.get('enrollment_system', {"enrollment_records": []})
        
        # 构建映射表(便于快速关联)
        teacher_id_map = {teacher.teacher_id: teacher for teacher in teachers}
        student_id_map = {student.student_id: student for student in students}
        assignment_id_map = {assign.assignment_id: assign for assign in assignments}
        
        # 1. 加载课程数据
        for course_data in course_data_list:
            try:
                if not isinstance(course_data, dict):
                    logger.warning("跳过无效的课程数据项")
                    continue
                
                # 关联课程所属教师(通过教师ID映射)
                # 关联课程所属教师(通过教师ID映射)
                teacher = None
                if "teacher_id" in course_data:
                    teacher = teacher_id_map.get(course_data["teacher_id"])
                    
                # 确保课程总是有一个教师
                if not teacher:
                    # 查找第一个可用的教师或创建默认教师
                    if teachers:
                        teacher = teachers[0]  # 使用第一个可用教师
                    else:
                        # 创建一个默认教师(这只是临时解决方案,实际应该从系统中获取)
                        teacher = Teacher("default_teacher_id", "default_teacher", "default_pass", "default_teacher@example.com")
                        teachers.append(teacher)  # 添加到教师列表中
                        teacher_id_map[teacher.teacher_id] = teacher
                
                # 创建Course实例
                course = Course(
                    course_id=course_data["course_id"],
                    course_name=course_data["course_name"],
                    course_description=course_data["course_description"],
                    teacher=teacher,
                    max_students=course_data["max_students"]
                )
                
                # 关联已选学生(通过学生ID映射)
                course.enrolled_students = []
                for student_id in course_data.get("enrolled_students", []):
                    if student_id in student_id_map:
                        course.enrolled_students.append(student_id_map[student_id])
                    else:
                        logger.warning(f"未找到学生ID: {student_id}")
                
                # 关联课程作业(通过作业ID映射)
                course.course_assignments = []
                for assign_id in course_data.get("course_assignments", []):
                    if assign_id in assignment_id_map:
                        course.course_assignments.append(assignment_id_map[assign_id])
                    else:
                        logger.warning(f"未找到作业ID: {assign_id}")
                
                courses.append(course)
            except Exception as e:
                logger.error(f"处理单个课程数据时出错:{str(e)}")
                continue  # 跳过当前课程,继续处理下一个
        
        # 2. 加载选课系统数据
        try:
            enrollment_system.enrollment_records = []
            for record in enrollment_data["enrollment_records"]:
                if not isinstance(record, dict):
                    continue
                
                student_id = record.get("student_id")
                course_id = record.get("course_id")
                
                if student_id in student_id_map:
                    # 查找对应课程
                    matching_courses = [c for c in courses if c.course_id == course_id]
                    if matching_courses:
                        try:
                            # 解析选课时间
                            enroll_time = None
                            try:
                                enroll_time = datetime.fromisoformat(record["enroll_time"])
                            except (ValueError, TypeError):
                                logger.warning(f"无效的选课时间格式: {record.get('enroll_time')}")
                                enroll_time = datetime.now()
                            
                            # 创建选课记录元组
                            enrollment_record = (
                                student_id_map[student_id],
                                matching_courses[0],  # 取第一个匹配的课程
                                enroll_time
                            )
                            enrollment_system.enrollment_records.append(enrollment_record)
                        except Exception as e:
                            logger.error(f"创建选课记录时出错:{str(e)}")
                            continue
        except Exception as e:
            logger.error(f"加载选课记录时出错:{str(e)}")
        
        logger.info(f"成功加载{len(courses)}个课程数据,{len(enrollment_system.enrollment_records)}条选课记录")
        return courses, enrollment_system
        
    except Exception as e:
        logger.error(f"加载课程和选课系统数据时发生严重错误:{str(e)}")
        # 返回空的课程列表和新的选课系统对象
        return [], EnrollmentSystem()

# ==============================
# 3. 作业与评分数据持久化(适配Serein模块)
# ==============================
def save_assignments_and_grading(assignments: list[object], grading_system: object):
    from Assignment_and_Grading.system_modules import GradingSystem
    from Assignment_and_Grading.course_task_classes import Assignment, Quiz
    """
    保存作业/测验数据与评分系统数据
    适配Serein定义的Assignment/Quiz类属性与GradingSystem类属性(grade_records、grade_scale)
    """
    ensure_storage_dir()
    # 作业/测验数据存储路径
    assign_file_path = os.path.join(DATA_STORAGE_DIR, f"assignments{DATA_FILE_EXTENSION}")
    # 评分数据存储路径
    grading_file_path = os.path.join(DATA_STORAGE_DIR, f"grading{DATA_FILE_EXTENSION}")

    # 1. 保存作业/测验数据(Serein定义的Assignment/Quiz类属性)
    assign_data_list = []
    for assign in assignments:
        assign_data = {
            "assign_type": assign.__class__.__name__,  # 标记类型(Assignment/Quiz)
            "assignment_id": assign.assignment_id,
            "assignment_title": assign.assignment_title,
            "assignment_content": assign.assignment_content,
            "due_date": assign.due_date.isoformat(),  # 转换为ISO格式字符串
            "course_id": assign.course.course_id if assign.course else None,  # 关联课程ID
            "submissions": [
                {"student_id": sub[0].student_id, "content": sub[1], "submit_time": sub[2].isoformat()}
                for sub in assign.submissions
            ]  # 存储学生提交记录,转换submit_time为ISO格式字符串
        }
        # 补充Quiz专属属性(若有,此处示例为通用结构)
        if isinstance(assign, Quiz):
            assign_data["quiz_duration"] = getattr(assign, "quiz_duration", None)  # 假设Quiz有"测验时长"属性
        assign_data_list.append(assign_data)

    with open(assign_file_path, "w", encoding="utf-8") as f:
        json.dump(assign_data_list, f, indent=4, ensure_ascii=False)
    print(f"作业/测验数据已保存至:{assign_file_path}")

    # 2. 保存评分系统数据(Serein定义的GradingSystem类属性)
    grading_data = {
        "grade_scale": grading_system.grade_scale,  # 成绩等级标准
        "grade_records": [
            {
                "student_id": record[0].student_id,
                "assignment_id": record[1].assignment_id,
                "score": record[2],
                "feedback": record[3]
            }
            for record in grading_system.grade_records
        ]  # 存储学生-作业-成绩记录
    }

    with open(grading_file_path, "w", encoding="utf-8") as f:
        json.dump(grading_data, f, indent=4, ensure_ascii=False)
    print(f"评分数据已保存至:{grading_file_path}")


def load_assignments_and_grading(courses: list, students: list) -> tuple[list, object]:
    from User_Management.user_classes import Student
    from Assignment_and_Grading.system_modules import GradingSystem
    from Assignment_and_Grading.course_task_classes import Assignment, Quiz
    from Course_Management_and_Enrollment.course_task_classes import Course
    import datetime
    import logging
    
    # 配置日志记录
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
    logger = logging.getLogger('data_persistence')
    
    """
    加载作业/测验数据与评分系统数据
    需传入已加载的Course/Student实例,用于关联作业与课程/学生
    """
    try:
        # 初始化默认返回值,确保始终返回有效元组
        assignments = []
        grading_system = GradingSystem()
        
        # 读取统一数据文件
        file_path = get_data_file_path()
        if not os.path.exists(file_path):
            logger.warning(f"数据文件不存在:{file_path},返回空列表与空评分系统")
            return assignments, grading_system
        
        # 读取数据
        with open(file_path, "r", encoding="utf-8") as f:
            all_data = json.load(f)
        
        # 从统一数据中提取作业数据
        assign_data_list = all_data.get('assignments', [])
        grading_data = all_data.get('grading_system', {"grade_scale": {}, "grade_records": []})
        
        # 验证传入参数
        if not isinstance(courses, list):
            logger.error("传入的courses参数不是列表类型")
            return assignments, grading_system
        
        if not isinstance(students, list):
            logger.error("传入的students参数不是列表类型")
            return assignments, grading_system
        
        # 构建映射表,加入类型检查
        course_id_map = {}
        for course in courses:
            if hasattr(course, 'course_id'):
                course_id_map[course.course_id] = course
            else:
                logger.warning("发现无效课程对象,缺少course_id属性")
                
        student_id_map = {}
        for student in students:
            if hasattr(student, 'student_id'):
                student_id_map[student.student_id] = student
            else:
                logger.warning("发现无效学生对象,缺少student_id属性")
        
        # 移出嵌套循环 - 先完成学生和课程映射表的构建,再处理作业数据
        for assign_data in assign_data_list:
            try:
                if not isinstance(assign_data, dict):
                    logger.warning("跳过无效的作业数据项")
                    continue

                # 获取作业类型,如果不存在则默认为Assignment
                assign_type = assign_data.get("assign_type", "Assignment")
                
                # 关联作业所属课程
                course = None
                if "course_id" in assign_data:
                    course = course_id_map.get(assign_data["course_id"])

                # 修复:检查必要字段是否存在
                required_fields = ["assignment_id"]
                if not all(field in assign_data for field in required_fields):
                    logger.warning(f"跳过缺少必要字段的作业数据")
                    continue
                
                # 确保作业标题和内容存在,使用默认值
                assignment_title = assign_data.get("assignment_title", assign_data.get("title", f"作业 {assign_data['assignment_id']}"))
                assignment_content = assign_data.get("assignment_content", assign_data.get("content", ""))
                due_date = assign_data.get("due_date", datetime.now().isoformat())
                
                # 加载Assignment或Quiz实例
                if assign_type == "Assignment" or assign_type is None:
                    assign = Assignment(
                        assignment_id=assign_data["assignment_id"],
                        assignment_title=assignment_title,
                        assignment_content=assignment_content,
                        due_date=due_date,
                        course=course
                    )
                elif assign_type == "Quiz":
                    assign = Quiz(
                        assignment_id=assign_data["assignment_id"],
                        assignment_title=assignment_title,
                        assignment_content=assignment_content,
                        due_date=due_date,
                        course=course,
                        quiz_duration=assign_data.get("quiz_duration")
                    )
                else:
                    logger.warning(f"跳过未知类型的作业数据: {assign_type}")
                    continue

                # 修复:正确恢复submissions - 处理字典格式的提交记录
                assign.submissions = {}
                try:
                    submissions_data = assign_data.get("submissions", {})
                    
                    # 检查submissions_data是字典还是列表
                    if isinstance(submissions_data, dict):
                        # 处理字典格式的提交记录
                        for student_id, sub_data in submissions_data.items():
                            if student_id in student_id_map:
                                # 构建正确的提交记录字典
                                submit_time = None
                                try:
                                    submit_time = datetime.fromisoformat(sub_data.get("submit_time", datetime.now().isoformat()))
                                except (ValueError, TypeError):
                                    submit_time = datetime.now()

                                assign.submissions[student_id] = {
                                    "content": sub_data.get("content", ""),
                                    "submit_time": submit_time,
                                    "is_late": sub_data.get("is_late", False),
                                    "score": sub_data.get("score", None),
                                    "status": sub_data.get("status", "submitted")
                                }
                    elif isinstance(submissions_data, list):
                        # 处理列表格式的提交记录(向后兼容)
                        for sub in submissions_data:
                            if isinstance(sub, dict) and sub.get("student_id") in student_id_map:
                                student_id = sub["student_id"]
                                # 构建正确的提交记录字典
                                submit_time = None
                                try:
                                    submit_time = datetime.fromisoformat(sub["submit_time"])
                                except (ValueError, TypeError):
                                    submit_time = datetime.now()

                                assign.submissions[student_id] = {
                                    "content": sub.get("content", ""),
                                    "submit_time": submit_time,
                                    "is_late": sub.get("is_late", False),
                                    "score": sub.get("score", None),
                                    "status": sub.get("status", "submitted")
                                }
                except Exception as e:
                    logger.error(f"恢复提交记录时出错:{str(e)}")
                
                # 确保提交计数正确
                assign.submission_count = len(assign.submissions)
                assignments.append(assign)
            except Exception as e:
                logger.error(f"处理单个作业数据时出错:{str(e)}")
                continue  # 跳过当前作业,继续处理下一个

        # 2. 加载评分系统数据
        grading_system.grade_scale = grading_data.get("grade_scale", {})  # 恢复成绩等级标准
        # 恢复成绩记录(关联学生与作业)
        try:
            grading_system.grade_records = []
            for record in grading_data.get("grade_records", []):
                if not isinstance(record, dict):
                    continue
                
                student_id = record.get("student_id")
                assignment_id = record.get("assignment_id")
                
                if student_id in student_id_map and assignment_id:
                    # 查找对应作业
                    matching_assignments = [a for a in assignments if a.assignment_id == assignment_id]
                    if matching_assignments:
                        try:
                            # 创建成绩记录元组
                            grade_record = (
                                student_id_map[student_id],
                                matching_assignments[0],  # 取第一个匹配的作业
                                record.get("score", 0),
                                record.get("feedback", "")
                            )
                            grading_system.grade_records.append(grade_record)
                        except Exception as e:
                            logger.error(f"创建成绩记录时出错:{str(e)}")
                            continue
        except Exception as e:
            logger.error(f"加载成绩记录时出错:{str(e)}")

        logger.info(f"成功加载{len(assignments)}个作业/测验数据,{len(grading_system.grade_records)}条评分记录")
        return assignments, grading_system
        
    except Exception as e:
        # 捕获所有未预期的异常,确保函数始终返回有效元组
        logger.error(f"加载作业和评分系统数据时发生严重错误:{str(e)}")
        # 返回空的作业列表和新的评分系统对象
        return [], GradingSystem()


# ==============================
# 4. 进度追踪与LMS主数据持久化(适配Daniel模块)
# ==============================
def save_progress_and_lms(progress_tracker: object, lms):
    from Progress_Tracking_CLI_DataPersistence.system_modules import ProgressTracker
    """
    保存进度追踪数据与LMS系统主数据
    适配Daniel定义的ProgressTracker类属性(progress_records等)与LMS类属性
    """
    ensure_storage_dir()
    # 进度追踪数据路径
    progress_file_path = os.path.join(DATA_STORAGE_DIR, f"progress{DATA_FILE_EXTENSION}")
    # LMS系统数据路径
    lms_file_path = os.path.join(DATA_STORAGE_DIR, f"lms{DATA_FILE_EXTENSION}")

    # 1. 保存进度追踪数据(Daniel定义的ProgressTracker类属性)
    # 修复:正确处理字典结构的progress_records
    progress_records_list = []
    for student_id, courses in progress_tracker.progress_records.items():
        for course_id, modules in courses.items():
            # 计算已完成的任务数
            completed_tasks = sum(1 for completed in modules.values() if completed)
            total_tasks = len(modules)
            # 添加到列表中,包含当前时间作为last_updated
            progress_records_list.append({
                "student_id": student_id,
                "course_id": course_id,
                "completed_tasks": completed_tasks,
                "total_tasks": total_tasks,
                "last_updated": datetime.now().isoformat()  # 使用当前时间并序列化为ISO格式
            })

    progress_data = {
        "progress_records": progress_records_list,
        "completed_tasks": getattr(progress_tracker, 'completed_tasks', 0),
        "total_tasks": getattr(progress_tracker, 'total_tasks', 0)
    }

    with open(progress_file_path, "w", encoding="utf-8") as f:
        json.dump(progress_data, f, indent=4, ensure_ascii=False)
    print(f"进度追踪数据已保存至:{progress_file_path}")

    # 2. 保存LMS系统数据(Daniel定义的LMS类属性)
    lms_data = {
        "system_status": getattr(lms, 'system_status', 'uninitialized'),  # 系统运行状态(如"已初始化")
        "current_user_id": lms.current_user.user_id if lms.current_user else None,  # 当前登录用户ID
        "last_save_time": datetime.now().isoformat()  # 修复:使用ISO格式序列化当前时间
    }

    with open(lms_file_path, "w", encoding="utf-8") as f:
        json.dump(lms_data, f, indent=4, ensure_ascii=False)
    print(f"LMS系统数据已保存至:{lms_file_path}")


def load_progress_and_lms(students: list, courses: list):
    from Progress_Tracking_CLI_DataPersistence.system_modules import ProgressTracker
    import datetime
    """
    加载进度追踪数据与LMS系统数据
    适配Daniel定义的ProgressTracker类属性(progress_records等)与LMS类属性
    """
    progress_tracker = ProgressTracker()
    lms_data = {"system_status": "uninitialized", "current_user_id": None, "last_save_time": None}
    
    # 读取统一数据文件
    file_path = get_data_file_path()
    if os.path.exists(file_path):
        try:
            with open(file_path, "r", encoding="utf-8") as f:
                all_data = json.load(f)
            
            # 从统一数据中提取进度追踪数据
            progress_data = all_data.get('progress_tracker', {"progress_records": [], "completed_tasks": 0, "total_tasks": 0})
            # 从统一数据中提取LMS系统数据
            lms_data = all_data.get('lms_system', lms_data)
            
            # 构建映射表
            student_id_map = {student.student_id: student for student in students if hasattr(student, 'student_id')}
            course_id_map = {course.course_id: course for course in courses if hasattr(course, 'course_id')}
            
            # 恢复进度追踪数据
            try:
                progress_tracker.progress_records = {}
                for record in progress_data["progress_records"]:
                    if record["student_id"] in student_id_map and record["course_id"] in course_id_map:
                        student = student_id_map[record["student_id"]]
                        course = course_id_map[record["course_id"]]
                        
                        if student.student_id not in progress_tracker.progress_records:
                            progress_tracker.progress_records[student.student_id] = {}
                        
                        # 假设进度数据是简单的完成/未完成状态
                        # 如果有更复杂的进度数据结构,这里需要根据实际情况调整
                        progress_tracker.progress_records[student.student_id][course.course_id] = {
                            "completed_tasks": record["completed_tasks"],
                            "total_tasks": record["total_tasks"],
                            "last_updated": record["last_updated"]
                        }
                
                progress_tracker.completed_tasks = progress_data.get("completed_tasks", 0)
                progress_tracker.total_tasks = progress_data.get("total_tasks", 0)
                print(f"成功加载进度追踪数据:进度记录")
            except Exception as e:
                print(f"加载进度追踪数据时出错:{str(e)}")
            
            print(f"成功加载LMS系统数据:状态={lms_data['system_status']}")
        except json.JSONDecodeError as e:
            print(f"数据文件解析错误:{str(e)}")
        except Exception as e:
            print(f"读取数据文件时出错:{str(e)}")
    else:
        print(f"数据文件不存在:{file_path},使用默认数据")
    
    return progress_tracker, lms_data


# ==============================
# 全局数据保存/加载(整合所有模块)
# ==============================
def save_all_data(users: list, courses: list, assignments: list, 
                  enrollment_system: object, grading_system: object, 
                  progress_tracker: object, lms):
    from User_Management.user_classes import User, Student, Teacher, Administrator  # 导入Eason的用户类
    from Course_Management_and_Enrollment.system_modules import EnrollmentSystem
    from Assignment_and_Grading.system_modules import GradingSystem
    from Assignment_and_Grading.course_task_classes import Assignment, Quiz
    """保存所有模块数据(一键调用,适配Daniel的LMS类save_data()方法)"""
    print("="*50 + " 开始保存所有系统数据 " + "="*50)
    save_users(users)
    save_courses_and_enrollment(courses, enrollment_system)
    save_assignments_and_grading(assignments, grading_system)
    save_progress_and_lms(progress_tracker, lms)
    print("="*50 + " 所有系统数据保存完成 " + "="*50)


def load_all_data() -> tuple[list, list, list, 
                             object, object, object, dict]:
    from User_Management.user_classes import User, Student, Teacher, Administrator  # 导入Eason的用户类
    from Course_Management_and_Enrollment.system_modules import EnrollmentSystem
    from Assignment_and_Grading.system_modules import GradingSystem
    from Assignment_and_Grading.course_task_classes import Assignment, Quiz
    """加载所有模块数据(一键调用,适配Daniel的LMS类load_data()方法)"""
    print("="*50 + " 开始加载所有系统数据 " + "="*50)
    # 加载顺序:先加载基础数据(用户、作业),再加载关联数据(课程、选课、评分、进度)
    # 1. 先加载用户(无依赖)
    users = load_users()
    # 2. 加载作业/测验(依赖课程,暂不关联)
    assignments, _ = load_assignments_and_grading(courses=[], students=users)
    # 3. 加载课程与选课系统(依赖教师、学生、作业)
    teachers = [u for u in users if isinstance(u, Teacher)]
    students = [u for u in users if isinstance(u, Student)]
    courses, enrollment_system = load_courses_and_enrollment(teachers, students, assignments)
    # 4. 重新加载作业/测验(补充课程关联)
    assignments, grading_system = load_assignments_and_grading(courses, students)
    # 5. 重新加载用户(补充课程、作业关联)
    users = load_users(courses, assignments)
    # 6. 加载进度追踪与LMS系统数据
    progress_tracker, lms_data = load_progress_and_lms(students, courses)
    # 7. 补充管理员的system_users关联(用户列表)
    for user in users:
        if isinstance(user, Administrator):
            user.system_users = [u for u in users if u.user_id in user.system_users]
    print("="*50 + " 所有系统数据加载完成 " + "="*50)
    return users, courses, assignments, enrollment_system, grading_system, progress_tracker, lms_data

def validate_all_data():
    """验证所有数据的完整性"""
    issues = []
    
    # 导入所需类
    from User_Management.user_classes import User, Teacher, Student
    from Course_Management_and_Enrollment.course_task_classes import Course
    
    # 验证所有课程都有教师
    for course in Course.all_courses():
        if not course.teacher:
            issues.append(f"错误:课程 {course.course_id}({course.course_name}) 没有关联教师")
    
    # 验证用户数据
    for user in User.all_users():
        if not user.user_id or not user.username or not user.email:
            issues.append(f"错误:用户数据不完整(ID:{user.user_id})")
    
    # 验证师生关系的一致性
    all_teachers = [u for u in User.all_users() if isinstance(u, Teacher)]
    for course in Course.all_courses():
        if course.teacher and course.teacher not in all_teachers:
            issues.append(f"错误:课程 {course.course_id} 的教师不在系统教师列表中")
    
    return issues